package com.nageoffer.onecoupon.merchant.admin.config;

import com.nageoffer.onecoupon.merchant.admin.common.context.UserContext;
import com.nageoffer.onecoupon.merchant.admin.common.context.UserInfoDTO;
import jakarta.annotation.Nullable;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 用户相关配置类
 **/


@Configuration
public class UserConfiguration implements WebMvcConfigurer {

    /**
     * 用户信息传输拦截器
     *
     * 该拦截器用于在请求处理之前将用户信息设置到上下文中，并在请求完成后清除用户信息。
     */
    @Bean
    public UserTransmitInterceptor userTransmitInterceptor() {
        return new UserTransmitInterceptor();
    }

    /**
     * 添加用户信息传递过滤器至相关路径拦截
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(userTransmitInterceptor())
                .addPathPatterns("/**");
    }

    static class UserTransmitInterceptor implements HandlerInterceptor {

        /**
         * 在请求处理之前执行
         * 该方法通过模拟的方式创建一个用户信息对象，并将其设置到当前线程的上下文中。
         * 后续如果需要展示后管功能，可以重构此逻辑。
         *
         * @param request  HTTP请求对象
         * @param response HTTP响应对象
         * @param handler  处理请求的处理器
         * @return 始终返回true，表示继续执行后续的拦截器和处理器
         * @throws Exception 如果发生异常
         */
        @Override
        public boolean preHandle(@Nullable HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Object handler) throws Exception {
            // 用户属于非核心功能，这里先通过模拟的形式代替。后续如果需要后管展示，会重构该代码
            UserInfoDTO userInfoDTO = new UserInfoDTO("1810518709471555585", "pdd45305558318", 1810714735922956666L);
            UserContext.setUser(userInfoDTO);
            return true;
        }


        /**
         * 在请求处理完成后执行
         *
         * 该方法用于清除当前线程上下文中的用户信息，避免内存泄漏。
         *
         * @param request   HTTP请求对象
         * @param response  HTTP响应对象
         * @param handler   处理请求的处理器
         * @param exception 请求处理过程中抛出的异常，如果没有异常则为null
         * @throws Exception 如果发生异常
         */
        @Override
        public void afterCompletion(@Nullable HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Object handler, Exception exception) throws Exception {
            UserContext.removeUser();
        }
    }
}
